package pl.edu.pw.polygen.ui.download;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import pl.edu.pw.polygen.MainWindow;
import pl.edu.pw.polygen.PolygenApplication;
import pl.edu.pw.polygen.beans.FileBean;
import pl.edu.pw.polygen.core.file.FileService;
import pl.edu.pw.polygen.generator.TriangularGeneratorService;
import pl.edu.pw.polygen.modeler.server.EditorServer;
import pl.edu.pw.polygen.modeler.server.util.ConverterService;
import pl.edu.pw.polygen.modeler.server.xml.MarshallService;
import pl.edu.pw.polygen.modeler.server.xml.PolygenData;
import pl.edu.pw.polygen.ui.file.EditorPanelFactory;
import pl.edu.pw.polygen.util.ApplicationHelper;
import pl.edu.pw.polygen.util.ApplicationHolder;

import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

@Component
@Scope("prototype")
public class TriangleWindow extends Window {

	private static final long serialVersionUID = 3439452761531103410L;
	private static final String windowName = "Triangle";

	private Logger LOG = Logger.getLogger(TriangleWindow.class);
	
	@Autowired
	private FileService fileService;
	
	@Autowired
	private TriangleForm downloadForm;
	
	@Autowired
	private TriangularGeneratorService triangularGeneratorService;
	
	@Autowired
	private EditorPanelFactory editorPanelFactory;
	
	private TriangleWindow instance;
	private Button okButton;
	private Button cancelButton;
	private HorizontalLayout buttonsLayout;

	public TriangleWindow() {
		super(windowName);
		instance = this;
	}

	@SuppressWarnings("unused")
	@PostConstruct
	private void initialize() {
		setModal(true);
		setResizable(false);
		VerticalLayout layout = (VerticalLayout) this.getContent();
		layout.setMargin(true);
		layout.setSpacing(true);
		layout.setSizeUndefined();

		layout.addComponent((AbstractLayout) downloadForm);
		layout.addComponent(getButtonsLayout());
		layout.setComponentAlignment(getButtonsLayout(), Alignment.BOTTOM_RIGHT);
	}
	
	public void init(FileBean fileBean) {
		downloadForm.setFileBean(fileBean);
	}

	private HorizontalLayout getButtonsLayout() {
		if(buttonsLayout==null){
			buttonsLayout = new HorizontalLayout();
			buttonsLayout.setSpacing(true);
			buttonsLayout.addComponent(getOkButton());
			buttonsLayout.addComponent(getCancelButton());
		}
		return buttonsLayout;
	}

	private Button getOkButton() {
		if (okButton == null) {
			okButton = new Button("Triangle");
			okButton.addListener(new ClickListener() {

				private static final long serialVersionUID = 982663756216569796L;

				@Override
				public void buttonClick(ClickEvent event) {
					if(downloadForm.isValid()){
						try{
						Long userId = ApplicationHelper.getLoggedUser().getId();
						String userName = ApplicationHelper.getLoggedUser().getUsername();
						
						String fileName = downloadForm.getFileName();
						String projectName = downloadForm.getProjectName();
						FileBean fileBean = fileService.findFile(fileName, projectName, userId);
						String diagramTypeOption = downloadForm.getDiagramType();
						double meshQuality = downloadForm.getMeshQuality();
						List<String> args = new ArrayList<String>();
						args.add(diagramTypeOption);
						args.add("-q");
						args.add(meshQuality+"");
						String polyName = userName + "_" + fileName;
						File polyFile = new File("c:\\polygen\\triangle\\" + polyName+".poly");
						
						MarshallService marshallService = new MarshallService();
						PolygenData polygenData = marshallService.unmarshall(fileBean.getContent());
						polyFile = ConverterService.convertToPoly(fileBean.getContent(), polyFile);
						args.add(polyFile.getAbsolutePath());
						triangularGeneratorService.executeTriangle(args);
						File triangleFile = new File("c:\\polygen\\triangle\\" + polyName + ".1.ele");
						File nodeFile = new File("c:\\polygen\\triangle\\" + polyName + ".1.node");
						if(triangleFile.exists() && nodeFile.exists()){
							polygenData = ConverterService.loadNodes(nodeFile);
							polygenData = ConverterService.loadTriangles(polygenData, triangleFile);
						}
						fileBean.setContent(marshallService.marshall(polygenData));
						fileService.saveFile(fileBean);
						
						triangleFile.delete();
						nodeFile.delete();
						polyFile.delete();
						
						MainWindow mainWindow = (MainWindow) ((PolygenApplication)ApplicationHolder.getApplication()).getMainWindow();
						if(mainWindow.isOpen(fileBean.getFileName())){
							EditorServer editorServer = mainWindow.getEditorServer(fileBean.getFileName());
							if(editorServer!=null){
								editorServer.uploadData(fileBean.getContent());
							}
						}else{
							mainWindow.addTab(fileBean,editorPanelFactory.getPanel());
						}
						
						ApplicationHelper.showNotification("Triangulation completed", "File '" + fileName +"' has been triangulated.");
						(instance.getParent()).removeWindow(instance);
						}catch(NumberFormatException e){
							ApplicationHelper.showError("Number format error", "Mesh quality has got wrong format!");
						}catch(Exception e){
							e.printStackTrace();
							ApplicationHelper.showError("Error", e.getMessage());
						}
					}
				}
			});
			okButton.setWidth("80px");
		}
		return okButton;
	}

	private Button getCancelButton() {
		if (cancelButton == null) {
			cancelButton = new Button("Cancel");
			cancelButton.addListener(new ClickListener() {

				private static final long serialVersionUID = 6840259256005300430L;

				@Override
				public void buttonClick(ClickEvent event) {
					(instance.getParent()).removeWindow(instance);
				}
			});
			cancelButton.setWidth("80px");
		}
		return cancelButton;
	}
	
	public void clear(){
		downloadForm.setFileName("");
	}

	
	
}
